<script setup>
import {ref, defineProps, watch} from "vue";
import {RequestSubmitHunyuanModelJobByText,RequestSubmitHunyuanModelJobByImage, RequestSearchJobByAI} from "@/api/Hunyuan.js";
import {ElLoading, ElMessage} from "element-plus";
import {RequestRiskeFileUpload} from "@/api/FileUpload.js"
import {Close} from "@element-plus/icons-vue";
import JobCard from "@/components/JobCard/JobCard.vue";
import {RequestSubmitJobToMine} from "@/api/Hunyuan.js";

const props = defineProps({
  genSameModelJob:{
    type:String,
    default:""
  },
});

watch(()=>props.genSameModelJob,(newVal)=>{
  if(newVal.length>0){
    console.log("监听到生成同款",newVal)
    downloadAndUploadImage(newVal,0)
    // 模型生成输入框
    // uploadFiles.value[0].viewImageUrl = newVal;
    currentGenType.value = '2';
  }
});

// 当前生成类型, 1 文生3D, 2 图生3D
const currentGenType = ref('1');
const genTypeOptions = ref([{label:'文生3D',value:'1'},{label:'图生3D',value:'2'}]);

// 模型生成输入框
const modelGenInputText = ref('');

// 提交文生图模型生成任务
async function submitHunyuanModelJobByText(){
  recommendDialogVisible.value = false;
  if(modelGenInputText.value.length<=5){
    ElMessage.warning("请输入至少5个文字以生成模型");
    return;
  }
  try{
    // 发送请求
    const res = await RequestSubmitHunyuanModelJobByText(modelGenInputText.value, modelNameSelectedValue.value, enablePBR.value, modelFaceCountSelectedValue.value, modelGenTypeOptionsSelectedValue.value);
    // 清空输入框
    modelGenInputText.value = '';
    console.log("提交结果",res);
    if(res.data.code === 200){
      ElMessage.success("任务提交成功，请前往任务列表等待生成完毕");
    }
  }catch (e) {
    ElMessage.error(e.message);
  }
}

// 提交图生3D模型生成任务
async function submitHunyuanModelJobByImage(){
  try{
    if(uploadFiles.value[0].viewImageUrl.length<1){
      ElMessage.warning("请至少上传一张正视图的图片");
      return;
    }
    // 过滤掉空图片
    const images = uploadFiles.value.filter(item=>item.viewImageUrl.length>0);

    const res = await RequestSubmitHunyuanModelJobByImage(images, modelNameSelectedValue.value, enablePBR.value, modelFaceCountSelectedValue.value, modelGenTypeOptionsSelectedValue.value);
    console.log("提交成功：",res);
    if(res.data.code === 200){
      ElMessage.success("任务提交成功，请前往任务列表等待生成完毕");
    }
  }catch (e) {
    console.log("图生3D任务提交失败",e);
  }
}

// 提交模型生成任务
function submitModelJob(){
  if(currentGenType.value === '1'){
    // 提交文生图模型生成任务
    // 更改，此处弹出模糊搜索后的模型给到用户，阻止用户进一步生成
    showLikeModel();
  }else if(currentGenType.value === '2'){
    // 提交图生3D模型生成任务
    submitHunyuanModelJobByImage();
  }
}

// 图片上传
const uploadFiles = ref([{
  "viewType": "front",
  "viewImageUrl": ""
},{
  "viewType": "back",
  "viewImageUrl": ""
},{
  "viewType": "left",
  "viewImageUrl": ""
},{
  "viewType": "right",
  "viewImageUrl": ""
}]);

// 选择上传图片后
function openFileSelected(index){
  console.log("选择上传图片",index);
  // 创建一个隐藏的 file input 元素
  const input = document.createElement('input');
  input.type = 'file';
  input.accept = 'image/jpeg,image/png'; // 限制图片类型

  input.onchange = (e) => {
    const file = e.target.files[0];
    if (!file) return;

    // 类型校验
    if (!['image/jpeg', 'image/png'].includes(file.type)) {
      ElMessage.warning('仅支持 JPG 和 PNG 格式的图片！');
      return;
    }

    // 文件大小校验（可选，比如限制 5MB）
    if (file.size > 8 * 1024 * 1024) {
      ElMessage.warning('图片大小不能超过 8MB！');
      return;
    }
    // 使用 FileReader 读取图片数据，生成预览 URL
    const reader = new FileReader();
    reader.onload = (e) => {
      // 更新 uploadFiles 中对应索引的 viewImageUrl
      uploadFiles.value[index] = {
        ...uploadFiles.value[index],
        viewImageUrl: e.target.result
      };
      // 上传图片
      uploadImage(file,index);
    };
    reader.readAsDataURL(file);
  };

  // 触发点击，打开文件选择器
  input.click();
}

// 上传图片
async function uploadImage(file,index){
  try {
    // 发送请求,上传文件
    const res = await RequestRiskeFileUpload(file);
    console.log("图片上传成功",res.data.data);
    if(res.data.code === 200){
      // 更新 uploadFiles 中对应索引的 viewImageUrl
      uploadFiles.value[index] = {
        ...uploadFiles.value[index],
        viewImageUrl: res.data.data
      };
    }
  }catch (e) {
    console.log("图片上传失败",e);
  }
}

// 移除图片
function removeImage(index){
  uploadFiles.value[index] = {
    "viewType": uploadFiles.value[index].viewType,
    "viewImageUrl": ""
  };
}

// 下载远程图片并上传
async function downloadAndUploadImage(url, index) {
  try {
    // 1. 检查 URL 是否有效
    if (!url) {
      ElMessage.error('图片 URL 无效');
      return;
    }

    // 2. 使用 fetch 下载图片
    const response = await fetch(url);
    if (!response.ok) {
      throw new Error(`下载失败: ${response.status} ${response.statusText}`);
    }

    // 3. 获取 Blob 数据
    const blob = await response.blob();

    // 4. 校验类型（必须是 image/jpeg 或 image/png）
    if (!['image/jpeg', 'image/png'].includes(blob.type)) {
      ElMessage.warning('仅支持 JPG 和 PNG 格式的图片！');
      return;
    }

    // 5. 校验大小（例如不超过 8MB）
    if (blob.size > 8 * 1024 * 1024) {
      ElMessage.warning('图片大小不能超过 8MB！');
      return;
    }

    // 6. 将 Blob 转换为 File 对象
    // 注意：我们需要一个文件名，可以从 URL 解析，或使用默认名
    const filename = url.split('/').pop() || `downloaded_image_${Date.now()}.jpg`;
    const file = new File([blob], filename, { type: blob.type });

    // 7. 调用你原有的 uploadImage 方法
    await uploadImage(file, index);

    console.log('图片下载并上传成功');
  } catch (error) {
    console.error('下载或上传失败:', error);
    ElMessage.error('图片下载失败，请检查链接是否有效');
  }
}

// 模型面数，默认4w
const modelFaceCountSelectedValue = ref(500000);
const modelFaceCount = ref([{
  label:'5w',
  value:40000
},{
  label:'12w',
  value:160000
},{
  label:'32w',
  value:320000
},{
  label:'50w',
  value:500000
}]);

// 模型生成方式
const modelGenTypeOptionsSelectedValue = ref('Normal');
const modelGenTypeOptions = ref([
  {
    label:"纹理几何",
    value:"Normal",
  },{
    label: "智能减面",
    value:"LowPoly"
  },{
    label: "白模",
    value: "Geometry"
  }
]);

// 是否启用PBR材质
const enablePBR = ref(true);

// 模型名称
const modelNameSelectedValue = ref('normal');
const modelNameOptions = ref([
  {
    label:"快速模型",
    value:"rapid"
  },{
    label:"默认模型",
    value:"normal"
  },{
    label:"专业模型",
    value:"pro"
  }
 ]);

// 模型推荐列表
const recommendModelList = ref([]);
// 全文搜索
async function requestSearchJob(){
  let loading = ElLoading.service({
    lock: true,
    fullscreen: true,
    text: 'AI 正在搜索相似模型...',
    background: 'rgba(0, 0, 0, 0.7)'
    // target: '.div' // 指定加载目标区域（可选），比如只在 dialog 内显示
  });

  try {
    if(modelGenInputText.value.length<=5){
      ElMessage.warning("请输入至少5个文字以生成模型");
      return;
    }
    const res = await RequestSearchJobByAI(modelGenInputText.value);
    console.log("全文搜索成功",res);
    if(res.data.code === 200){
      ElMessage.success("搜索成功");
      recommendModelList.value = res.data.data;
      if(res.data.data.length>0){
        recommendDialogVisible.value = true;
      }else{
        submitHunyuanModelJobByText();
      }
    }
  }catch (e) {
    console.log("全文搜索失败",e);
  }finally {
    if (loading) {
      loading.close(); // 确保 close 被调用
    }
  }
}

// 推荐框展示
const recommendDialogVisible = ref(false);
// 向用户展示相似的输入文本模型
async function showLikeModel(){
  try{
    requestSearchJob();
  }catch (e) {
    console.log("AI搜索失败",e);
  }
}
// 推荐框被点击
async function recommendSelected(job){
  console.log("相似模型被点击",job)
  try{
    const res = await RequestSubmitJobToMine(job.id);
    if(res.data.code === 200){
      ElMessage.success("提交成功");
      recommendDialogVisible.value = false;
    }
  }catch (e) {
    console.log("相似模型点击失败",e);
  }
}

</script>

<template>
  <div class="body">
    <!--文生3D/图生3D按钮-->
    <div class="genType">
      <el-segmented
          v-model="currentGenType"
          :options="genTypeOptions"
      />
    </div>
    <el-divider />

    <div>
      <el-scrollbar height="400px" class="scrollbarBody">
        <!--文生3D输入框-->
        <div v-if="currentGenType === '1'">
          <el-input
              type="textarea"
              :rows="8"
              maxlength="150"
              placeholder="请输入想要生成的内容。例如：一只在奔跑中的马."
              show-word-limit
              v-model="modelGenInputText">
          </el-input>
        </div>
        <!--图生3D输入框-->
        <div v-else class="imageContainer">
          <div v-for="index in 4"  class="imageInput-wrapper">
            <!-- 新增关闭按钮 -->
            <div class="closeBtn"
                 @click="removeImage(index-1)"
                 v-if="uploadFiles[index-1].viewImageUrl.length > 0">
              <el-icon><Close /></el-icon>
            </div>
            <div v-if="index === 1" @click="openFileSelected(index-1)">
              <img class="imag" v-if="uploadFiles[index-1].viewImageUrl.length > 0" :src="uploadFiles[index-1].viewImageUrl"  alt="正视图"></img>
              <div v-else class="noImageContainer">
                <img src="/font.png" alt="正视图"/>
                <div class="label-wrapper">
                  正视图
                  <span class="required-star">*</span>
                </div>
              </div>
            </div>
            <div v-else-if="index === 2" @click="openFileSelected(index-1)">
              <img class="imag" v-if="uploadFiles[index-1].viewImageUrl.length > 0" :src="uploadFiles[index-1].viewImageUrl" ></img>
              <div v-else class="noImageContainer">
                <img src="/back.png" alt="后视图"/>
                <div>
                  后视图
                </div>
              </div>
            </div>
            <div v-else-if="index === 3" @click="openFileSelected(index-1)">
              <img class="imag" v-if="uploadFiles[index-1].viewImageUrl.length > 0" :src="uploadFiles[index-1].viewImageUrl"  alt="左视图"></img>
              <div v-else class="noImageContainer">
                <img src="/right.png" alt="左视图"/>
                <div>
                  左视图
                </div>
              </div>
            </div>
            <div v-else-if="index === 4" @click="openFileSelected(index-1)">
              <img class="imag" v-if="uploadFiles[index-1].viewImageUrl.length > 0" :src="uploadFiles[index-1].viewImageUrl"  alt="右视图"></img>
              <div v-else class="noImageContainer">
                <img src="/left.png" alt="右视图"/>
                <div>
                  右视图
                </div>
              </div>
            </div>
          </div>
        </div>

<!--        通用的-->
<!--        是否开启PBR材质-->
        <div style="display: flex;flex-direction: row;margin: 5px 0;align-items: center">
          <div>
            <el-text>PBR材质</el-text>
          </div>
          <div style="margin-left: 20px;">
            <el-switch v-model="enablePBR" />
          </div>
        </div>
        <!--模型名称-->
        <div>
          <div style="margin: 5px 0;">
            <el-text>模型</el-text>
          </div>
          <el-radio-group v-model="modelNameSelectedValue" size="large">
            <el-radio-button
                v-for="item in modelNameOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"/>
          </el-radio-group>
        </div>
<!--        模型面数-->
        <div v-if="modelNameSelectedValue === 'pro'">
          <div style="margin: 5px 0;">
            <el-text>模型面数</el-text>
          </div>
          <el-radio-group v-model="modelFaceCountSelectedValue" size="large">
            <el-radio-button
              v-for="item in modelFaceCount"
              :key="item.value"
              :label="item.label"
              :value="item.value"/>
          </el-radio-group>
        </div>
<!--        模型生成方式-->
        <div v-if="modelNameSelectedValue === 'pro'">
          <div style="margin: 5px 0;">
            <el-text>生成类型</el-text>
          </div>
          <div>
            <el-radio-group v-model="modelGenTypeOptionsSelectedValue" placeholder="Select" style="width: 240px">
              <el-radio-button
                  v-for="item in modelGenTypeOptions"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"/>
            </el-radio-group>
          </div>
        </div>
        <div style="margin-bottom: 20px">
        </div>
      </el-scrollbar>
    </div>
    <!--开始生成按钮-->

    <el-button style="margin-top: 20px;" type="primary" @click="submitModelJob">立即生成</el-button>
  </div>

  <!--弹出框-->
  <div>
    <el-dialog v-model="recommendDialogVisible" title="以下模型，是否有符合您预期呢？点击保存" width="80%">
      <div>
        <div>
          <el-button @click="submitHunyuanModelJobByText" type="primary">仍然生成</el-button>
        </div>
        <div style="display: grid;grid-template-columns: repeat(4, 1fr);margin-top: 20px;">
          <JobCard style="margin: 5px 20px;" v-for="item in recommendModelList" :job-data="item" @cardClicked="recommendSelected(item)"></JobCard>
        </div>
      </div>

    </el-dialog>
  </div>
</template>

<style scoped lang="scss">

.body{
  display: flex;
  flex-direction: column;
}

.genType{
  margin: auto;
}

.imageContainer{
  display: flex;
  flex-wrap: wrap;
  justify-content: space-evenly;
}
// 图片
.imag {
  width: 100%;
  height: 100%;
  border-radius: 10px;
  display: block;
  padding: 2px;
  object-fit: contain;
}

.noImageContainer{
  font-size: 12px;
  color: #656f81;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative; // 为星号提供定位上下文
}

/* 每个图片项的容器（加相对定位） */
.imageInput-wrapper {
  width: 8vw;
  height: 8vw;
  border: #eaecef 2px solid;
  margin-bottom: 10px;
  border-radius: 10px;
  cursor: pointer;
  position: relative;        // ✅ 必须：为绝对定位提供上下文
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 悬浮时显示关闭按钮 */
.imageInput-wrapper:hover .closeBtn {
  opacity: 1;
}

/* 关闭按钮 */
.closeBtn {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 24px;
  height: 24px;
  background-color: rgba(0, 0, 0, 0.6);
  color: white;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.3s ease;
  z-index: 10;
  pointer-events: auto; /* 允许交互 */
}

.label-wrapper {
  position: relative;
  display: inline-block;
}

.required-star {
  position: absolute;
  right: -10px;
  color: red;
  font-size: 16px;
  font-weight: bold;
  pointer-events: none; // 防止干扰点击
}

// 滚动框内
.scrollbarBody{
  display: flex;
  flex-direction: column;
  //align-items: center;
}

</style>
